var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var ngMin = require('gulp-ng-annotate');
var base64 = require('gulp-base64');

var less = require('gulp-less');
var path = require('path');
var cleanCSS =require('less-plugin-clean-css'),
	minify = new cleanCSS({advanced: true});

var request = require('request');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var merge = require('merge2');
require('shelljs/global');

//shouldn't pollution global namespace...
var indexCache,
	stylePath = '<link rel="stylesheet" href="./style.css"/>',
	jsPath = '<script src="./app.js"></script>',
	destination = './release'
	;

gulp.task('default', ['js']);

gulp.task('$read', function (taskDone) {
	//read index.html from file system
	indexCache = cat('index.html').split('\n').map(function (string) {
		return string.trim();
	}).filter(function (string) {
		if (string.indexOf('node_module') > -1) { return false; }

		if (string === '') { return false; }
		
		return string.indexOf('<!--') === -1;
	});
	console.log('\tstep 1 - reading index.html finished');
	taskDone();
});

gulp.task('$css', ['$read'], function () {
	var match,//result of regex match
		fileURL, //matched file path in tag
		localFiles = [], //local files that gulp.src needs
		cdnFiles = [],  //files on cdn
		index = 0, //insert the result at this position of index.html array
		streams = []//array to store all stream promise
		;
	
	indexCache.forEach(function (string, i, self) {
		//matches style
		if (match = /href="(\S+\.css)"/.exec(string)) {
			fileURL = match[1];//should look like ./XXX.css
			//cdn
			if (fileURL.indexOf('cdn') > -1) {
				cdnFiles.push(fileURL);
			}
			//local file
			else {
				localFiles.push(fileURL);
			}
			index = index || i;
			//remove current line
			self.splice(i, 1, '<!-- deleted style -->');
		}
	});
	//insert concat file's url
	indexCache.splice(index, 0, stylePath);
	
	//request cdn
	cdnFiles.forEach(function (url) {
		streams.push(request(url).pipe( source('cdn.' + path.parse(url).base) ));
	});
	//combine stream with local files
	var mergeCss = merge();
	mergeCss.add(streams);
	mergeCss.add(gulp.src(localFiles));
	
	console.log('\tstep 2 - combine css files');
	return mergeCss
		.pipe(buffer())
		.pipe(concat('style.css'))
		.pipe(base64())
		.pipe(less({
			plugins: [minify]
		}))
		.pipe(gulp.dest(destination));
});

gulp.task('$js', ['$css'], function () {
	var match,//result of regex match
		fileURL, //matched file path in tag
		localFiles = [], //local files that gulp.src needs
		cdnFiles = [],  //files on cdn
		index = 0, //insert the result at this position of index.html array
		streams = []//array to store all stream promise
		;
	 
	indexCache.forEach(function (string, i, self) {
		//matches javascript file
		if (match = /src="(\S+\.js)"/.exec(string)) {
			fileURL = match[1]; //should look like ./XXX.js
			//cdn
			if (fileURL.indexOf('cdn') > -1) {
				cdnFiles.push(fileURL);
			}
			//local file
			else {
				localFiles.push(fileURL);
			}
			index = index || i;
			
			self.splice(i, 1, '<!-- deleted javascript -->');
		}
	});
	//insert concat file's url
	indexCache.splice(index, 0, jsPath);
	
	//request cdn
	cdnFiles.forEach(function (url) {
		streams.push(request(url).pipe( source('cdn.' + path.parse(url).base) ));
	});
	//combine stream with local files
	var mergeJS = merge();
	//order is important, add them one by one
	streams.forEach(function (item) {
		mergeJS.add(item);
	});
	mergeJS.add(gulp.src(localFiles));
	
	console.log('\tstep 3 - combine js files');
	return mergeJS
		.pipe(buffer())
		.pipe(concat('app.js'))
		.pipe(ngMin())
		.pipe(uglify())
		.pipe(gulp.dest(destination));
});

gulp.task('release', ['$js'], function (taskDone) {
	indexCache.join('\n').to(destination + '/probe.html');
	
	cp('-r', './src/dialog/*', destination + '/dialog');
	
	taskDone();
});

gulp.task('watch', function () {
	gulp.watch(['./resources/less/*.less'], ['less']);
});

gulp.task('less', function(){
	return gulp.src('./resources/less/*.less')
		.pipe(less({
			plugins: [minify]
		}))
		.pipe(gulp.dest('./resources/css'));
});